#include <iostream>
#include <string>
using namespace std;

#if 0
class Base{
	public:
		virtual void TestFunc1(){
			cout << "Base::TestFunc1" << endl;
		}
		virtual Base& TestFunc2(){
			cout << "Base::TestFunc2" << endl;
			return *this;
		}
		virtual void TestFunc3(){
			cout << "Base::TestFunc3" << endl;
		}
		void TestFunc4(){
			cout << "Base::TestFunc4" << endl;
		}
		~Base(){
			cout << "Base::~Base" << endl;
		}
};

class Derived : public Base
{
	public:
		//派生类重写基类的虚函数，要求函数名，参数，返回值列表完全相同
		//	//协变除外，协变可以返回对象的指针或引用
		virtual void TestFunc1(){
			cout << "Derived::TestFunc1" << endl;
		}
		virtual Derived& TestFunc2(){
			cout << "Derived::TestFunc2" << endl;
			return *this;
		}

		//同名隐藏
		virtual void TestFunc3(int){
			cout << "Derived::TestFunc3" << endl;
		}

		//同名隐藏
		//在基类和派生类中只要不构成重写就是同名隐藏
		virtual void TestFunc4(){
			cout << "Derived::TestFunc4" << endl;
		}
		virtual ~Derived(){
			cout << "Derived::~Derived" << endl;
		}
};

void TestFunc(Base& b)
{
	b.TestFunc1();
	b.TestFunc2();
	b.TestFunc3();
	b.TestFunc4();

	Base* pb = &b;
	delete pb;

	pb->TestFunc1();
}
int main()
{
	Base b;
	Derived d;

	TestFunc(d);
	TestFunc(d);

	Base* pb = new Base;
	delete pb;

	pb = new Derived;
	delete pb;

	system("pause");
	return 0;
}
#endif


#if 0
//抽象类：包含纯虚函数的类
class Person{
	public:
		//包含纯虚函数的类不能实例化出对象，只有在派生类中重定义之后，派生类才能实例化出对象
		virtual void GoToWc() = 0;
	public:
		string _name;
		int age;
};

class Man : public Person{
	public:
		virtual void GoToWc(){
			cout << "Go To Nan Mao Zi!!\n" << endl;
		}
	public:
		string _gender;
};

class Woman : public Person{
	public:
		virtual void GoToWc(){
			cout << "Go To Nv Mao Zi!!\n" << endl;
		}
		void ShowInfo(){
			cout << _name << endl;
		}
	public:
		string _gender;
};

void Test(){
	Man Jack;
	Woman Lucy;

	Jack.GoToWc();
	Lucy.GoToWc();
}

int main(){
	Test();

	system("pause");
	return 0;
}
#endif

class Car{
	public:
		virtual void Drive() = 0;
};

class Benz :public Car {
	public:
		virtual void Drive(){
			cout << "Drive Benz" << endl;
		}
};

class Lexus : public Car{
	public:
		virtual void Drive(){
			cout << "Drive Lexus" << endl;
		}
};

void TestDrive(Car& c)
{
	c.Drive();
}

int main()
{
	Car* c;

	Benz bz;
	Lexus lexus;

	bz.Drive();
	lexus.Drive();

	return 0;
}
